﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.Diagnostics;
using StartupTaskRunner.Logging;
using StartupTaskRunner.Configuration;

namespace StartupTaskRunner
{
    class Program
    {
        static void Main(string[] args)
        {
            ConfigType configuration = null;
            CatchUnhandledException();

            IStorageDAL storageDal = StorageDALFactory.GetStorageDAL(); 
           
            using (new LogContext("StartupTaskRunner"))
            {
                try
                {
                    // we use the StartupTaskRunner as task
                    if (args.Length > 0)
                    {
                        Logger.WriteMessage("UseMode: Startup Task");
                        StartupArguments arguments = new StartupArguments(args);
                        configuration = ConfigType.ReadConfigurationFromFile(arguments.ConfigFile);
                        configuration.DevelopmentMode = arguments.DevelopmentMode;
                    }
                    // we are using the StartupTaskRunner as module
                    // So get the settings from blobstorage
                    else
                    {
                        configuration = GetSettingsFromBlobStorage(storageDal);
                    }

                    if (configuration == null)
                    {
                        throw new ApplicationException("The configuration is not valid.");
                    }

                    StartupTaskRunner runner = new StartupTaskRunner(configuration);
                    runner.Execute();
                }
                catch (Exception ex)
                {
                    Logger.WriteMessage("Exception occurred: {0}", ex);
                }
            }

            // Upload the log file to the default container
            UploadLogfile(configuration.BlobStorage.defaultContainer);
        }

        private static ConfigType GetSettingsFromBlobStorage(IStorageDAL storageDal)
        {
            Logger.WriteMessage("UseMode: Plugin Module");

            //if (!RoleEnvironment.IsAvailable)
            //{
            //    throw new ApplicationException("Role Environment not available, unable to get settings.");
            //}

            string connectionString = storageDal.GetConnectionString();
            string container = storageDal.Getcontainer();
            string configurationFilename = storageDal.GetconfigurationFilename();

            // use the setting to get the config file from blobstorage
            Logger.WriteMessage("ConfigurationSettings from RoleEnvironment:{3}ConnectionString: {0}{3}StartupResourcesContainer: {1}{3}ConfigurationFilename: {2}"
                , connectionString, container, configurationFilename, Environment.NewLine);

            string configurationContent = storageDal.DownloadFileContentFromBlob(connectionString, container, configurationFilename);

            Logger.WriteMessage("Content of ConfigurationFile:{1}{0}", configurationContent, Environment.NewLine);
            return ConfigType.ReadConfiguration(configurationContent);
        }

        /// <summary>
        /// Uploads the logfile to specified container
        /// </summary>
        /// <param name="containerName"></param>
        private static void UploadLogfile(string containerName)
        {
            // Close the log file
            Logger.Close();
            string logfile = Logger.GetLogFilename();

            IStorageDAL dal = StorageDALFactory.GetStorageDAL();
            dal.UploadFileToBlob(logfile, containerName, logfile);
        }

        private static void CatchUnhandledException()
        {
            AppDomain currentDomain = AppDomain.CurrentDomain;
            currentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionHandler);
        }

        static void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs e)
        {
            Logger.WriteMessage("Unhandled Exception occurred: {0}", e.ExceptionObject);
        }
    }
}
